home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et-2_2.lha / et2.2 / src / TextCmd.C < prev    next >
C/C++ Source or Header  |  1990-12-04  |  11KB  |  447 lines

  1. //$QuickPasteSelector,TextCommand,CutCopyCommand,ChangeStyleCommand,ExtendRangeSelector$
  2. //$PasteCommand,TypeingCommand,CopyDragPasteSelector,RangeSelector$
  3.  
  4. #include "TextView.h" 
  5. #include "TextCmd.h"
  6. #include "CmdNo.h"
  7.  
  8. //---- range functions ---------------------------------------------------------
  9.  
  10. void CharacterRange(Text*, int at, int *start, int *end)
  11. {
  12.     *start= *end= at;    
  13. }
  14.  
  15. void WordRange(Text *t, int at, int *start, int *end)
  16. {
  17.     t->GetWordBoundaries(at, start, end);
  18. }
  19.  
  20. void ParagraphRange(Text *t, int at, int *start, int *end)
  21. {
  22.     t->GetParagraphBoundaries(at, start, end);
  23. }
  24.  
  25. //---- RangeSelector -----------------------------------------------------------
  26.  
  27. RangeSelector::RangeSelector(class TextView *t, TextRangeFP f)
  28. {
  29.     tv= t;
  30.     range= f;
  31. }
  32.  
  33. Command *RangeSelector::TrackMouse(TrackPhase tp, Point, Point np, Point)
  34. {
  35.     SelPoint nextp;
  36.     int start, end;
  37.     
  38.     np= np-tv->GetInnerOrigin();
  39.     
  40.     switch (tp) {
  41.     case eTrackPress:
  42.     tv->DoneTypeing();
  43.     tv->inTextSelector= TRUE;
  44.     tv->PointToPos(np, &nextp.viewp, &nextp.line, &nextp.ch);
  45.     range(tv->GetText(), nextp.ch, &start, &end);
  46.     DoPress(nextp, start, end);
  47.     break;
  48.     
  49.     case eTrackMove:
  50.     tv->PointToPos(np, &nextp.viewp, &nextp.line, &nextp.ch);
  51.     range(tv->GetText(), nextp.ch, &start, &end);
  52.     DoMove(nextp, start, end);
  53.     break;
  54.     
  55.     case eTrackRelease:
  56.     tv->inTextSelector= FALSE;
  57.     if ((tv->start.line == tv->end.line) && tv->Caret())
  58.         tv->InvalidateSelection();
  59.     tv->NormSelection();  
  60.     return gNoChanges;
  61.     }
  62.     return this;
  63. }
  64.  
  65. void RangeSelector::DoPress(SelPoint, int s, int e)
  66. {
  67.     tv->PrivSetSelection(s, e, FALSE);
  68.     startp= tv->start;
  69.     endp= tv->end;
  70. }
  71.  
  72. void RangeSelector::DoMove(SelPoint nextp, int s, int e)
  73. {
  74.     if (nextp.ch <= startp.ch) {
  75.     tv->CharToPos (nextp.ch= s, &nextp.line, &nextp.viewp);
  76.     if (!nextp.IsEqual(tv->start)) {
  77.         tv->InvalidateRange(nextp.line, nextp.viewp, tv->start.line, tv->start.viewp);
  78.         tv->start= nextp;
  79.     }
  80.     else if (tv->end.ch > endp.ch && !endp.IsEqual(tv->end)) {
  81.         tv->InvalidateRange(endp.line, endp.viewp, tv->end.line, tv->end.viewp);
  82.         tv->end= endp;
  83.     }            
  84.     } else {
  85.     tv->CharToPos(nextp.ch= e, &nextp.line, &nextp.viewp);
  86.     if (!nextp.IsEqual(tv->end)) {
  87.         tv->InvalidateRange(tv->end.line, tv->end.viewp, nextp.line, nextp.viewp);
  88.         tv->end= nextp;
  89.     } 
  90.     else if (tv->start.ch < startp.ch && !startp.IsEqual(tv->start)) {
  91.         tv->InvalidateRange(tv->start.line, tv->start.viewp, startp.line, startp.viewp);
  92.         tv->start= startp;
  93.     }
  94.     }
  95. }
  96.  
  97. //---- ExtendRangeSelector ----------------------------------------------------
  98.  
  99. ExtendRangeSelector::ExtendRangeSelector(TextView *tv, TextRangeFP rf) 
  100.                             : RangeSelector(tv, rf)
  101. {
  102.     swap= FALSE;
  103. }
  104.  
  105. void ExtendRangeSelector::DoPress(SelPoint nextp, int s, int e)
  106. {
  107.     SelPoint tmp;
  108.     
  109.     startp.ch= s;
  110.     endp.ch= e;
  111.     if (nextp.ch <= tv->start.ch) {     // extend at start 
  112.     tv->CharToPos(startp.ch, &startp.line, &startp.viewp);
  113.     tv->InvalidateRange(startp.line, startp.viewp, tv->start.line, tv->start.viewp);
  114.     tv->start= startp;
  115.     swap= TRUE;
  116.     } else {                            // extend at end
  117.     tv->CharToPos(endp.ch, &endp.line, &endp.viewp);
  118.     tv->InvalidateRange(tv->end.line, tv->end.viewp, endp.line, endp.viewp);
  119.     tv->end= endp;
  120.     }
  121.     startp= nextp;
  122. }
  123.  
  124. void ExtendRangeSelector::DoMove(SelPoint nextp, int s, int e)
  125. {
  126.     if (swap) {
  127.     swap= FALSE;
  128.     SwapSelPoints(tv->start, tv->end);
  129.     } 
  130.     if (nextp.ch < startp.ch)
  131.     tv->CharToPos (nextp.ch= s, &nextp.line, &nextp.viewp);
  132.     else
  133.     tv->CharToPos(nextp.ch= e, &nextp.line, &nextp.viewp);
  134.     
  135.     if (!nextp.IsEqual(tv->end)) {
  136.     tv->InvalidateRange(nextp.line, nextp.viewp, tv->end.line, tv->end.viewp);
  137.     tv->end= nextp;
  138.     } 
  139. }
  140.  
  141. //---- QuickPasteSelector ------------------------------------------------------
  142.  
  143. QuickPasteSelector::QuickPasteSelector(class TextView *tv, int f, int t)
  144.                                  : RangeSelector(tv)
  145.     from= f;
  146.     to= t;
  147. }
  148.  
  149. Command *QuickPasteSelector::TrackMouse(TrackPhase tp, Point ap, Point pp, Point np)
  150. {
  151.     Command *cmd= RangeSelector::TrackMouse(tp, ap, pp, np);
  152.     if (tp == eTrackRelease) {
  153.     if (tv->Caret()) {
  154.         tv->SetSelection(from, to);
  155.         return gNoChanges;
  156.     }
  157.     Text *t= tv->SelectionAsText();
  158.     tv->SetSelection(from, to);
  159.     return new PasteCommand(tv, t); 
  160.     }
  161.     return cmd;
  162. }
  163.  
  164. //---- CopyDragPasteSelector ---------------------------------------------------
  165.  
  166. CopyDragPasteSelector::CopyDragPasteSelector(class TextView *tvp, int f, int t)
  167.     from= f;
  168.     to= t;
  169.     tv= tvp;
  170. }
  171.  
  172. Command *CopyDragPasteSelector::TrackMouse(TrackPhase tp, Point, Point, Point)
  173. {
  174.     if (tp == eTrackRelease) {
  175.     int cfrom, cto;
  176.     tv->GetSelection(&cfrom, &cto);
  177.     tv->SetSelection(from, to, TRUE);
  178.     if (tv->Caret()) {
  179.         tv->SetSelection(cfrom, cto, TRUE);
  180.         return gNoChanges;
  181.     }
  182.     Text *t= tv->SelectionAsText();
  183.     tv->SetSelection(cfrom, cto, TRUE);
  184.     return new PasteCommand(tv, t); 
  185.     }
  186.     return this;
  187. }
  188.  
  189. void CopyDragPasteSelector::TrackFeedback(Point, Point np, bool on)
  190. {
  191.     if (on) {
  192.     Point p;
  193.     int line, ch;
  194.     tv->PointToPos(np, &p, &line, &ch);  
  195.     tv->SetSelection(ch, ch, TRUE);
  196.     }
  197. }
  198.  
  199. //----- TextCommand Methods ----------------------------------------------------
  200.  
  201. AbstractMetaImpl(TextCommand, (TP(tv), TP(oldText), T(oldStart), T(oldEnd), 0));
  202.  
  203. TextCommand::TextCommand (TextView *t, int cmdNo, char *cmdName, bool save)
  204.                             : Command(cmdNo, cmdName)
  205. {
  206.     tv= t;
  207.     tv->GetSelection(&oldStart, &oldEnd);
  208.     oldText= (Text*)tv->GetText()->New();
  209.     if (save && oldStart != oldEnd) // save old text
  210.     tv->Copy(oldText);
  211. }
  212.  
  213. TextCommand::~TextCommand ()
  214. {
  215.     SafeDelete(oldText);
  216.  
  217. void TextCommand::RestoreSelection ()
  218. {
  219.     tv->SetSelection(oldStart, oldEnd, FALSE);
  220. }
  221.  
  222. void TextCommand::RedoIt()
  223. {
  224.     RestoreSelection();
  225.     DoIt();
  226.     tv->RevealSelection();
  227. }
  228.  
  229. //----- CutCopyCommand Methods -------------------------------------------------
  230.  
  231. MetaImpl0(CutCopyCommand);
  232.  
  233. CutCopyCommand::CutCopyCommand(TextView *t, int cmdNo, char *cmdName) 
  234.                             : TextCommand(t, cmdNo, 0)
  235.     if (cmdName == 0) {
  236.     if (cmdNo == cCUT)
  237.         cmdName= "cut text";
  238.     else if (cmdNo == cCOPY)
  239.         cmdName= "copy text";
  240.     }
  241.     SetName(cmdName);
  242.     if (cmdNo == cCOPY)
  243.     ResetFlag(eCmdCausesChange);
  244. }
  245.  
  246. void CutCopyCommand::DoIt()
  247. {
  248.     if (GetId() == cCOPY)
  249.     return;
  250.     tv->Cut();
  251.     tv->RevealSelection();
  252. }  
  253.  
  254. void CutCopyCommand::UndoIt()
  255. {
  256.     Text *t= tv->GetText();    
  257.  
  258.     if (GetId() == cCUT) {
  259.     tv->SetSelection(oldStart, oldStart, FALSE);
  260.     if (oldText->Size()) 
  261.         tv->Paste(oldText);
  262.     RestoreSelection();
  263.     tv->RevealSelection();
  264.     }
  265. }
  266.  
  267. //----- Paste Command Methods --------------------------------------------------
  268.  
  269. MetaImpl(PasteCommand, (TP(pastetext), T(newStart), T(newEnd), 0));
  270.  
  271. PasteCommand::PasteCommand(TextView *t, Text *pt, int cmdNo, char *cmdName) 
  272.             : TextCommand(t, cmdNo, cmdName ? cmdName : "paste text")
  273. {
  274.     pastetext= pt;
  275. }
  276.  
  277. PasteCommand::~PasteCommand()
  278. {
  279.     SafeDelete(pastetext);
  280. }
  281.  
  282. void PasteCommand::DoIt()
  283. {
  284.     tv->Paste(pastetext);
  285.     tv->GetSelection(&newStart, &newEnd);
  286.     tv->RevealSelection();
  287. }  
  288.  
  289. void PasteCommand::UndoIt()
  290. {
  291.     tv->SetSelection(oldStart, newEnd, FALSE);
  292.     tv->Cut();
  293.     if (oldText->Size())
  294.     tv->Paste(oldText);
  295.     RestoreSelection();
  296.     tv->RevealSelection();
  297. }
  298.  
  299. //----- TypeInCommand Command Methods ------------------------------------------
  300.  
  301. MetaImpl(TypeingCommand, (TP(backspaceBuf), TP(newText), T(newStart), 0));
  302.  
  303. TypeingCommand::TypeingCommand(TextView *t, int cmdNo, char *cmdName) 
  304.                            : TextCommand(t, cmdNo, cmdName) 
  305. {
  306.     Text *txt= tv->GetText();
  307.     backspaceBuf= (Text*) txt->New();
  308.     newText= (Text*) txt->New();
  309.     newStart= oldStart;
  310.     completed= FALSE;
  311.     ResetFlag(eCmdDoDelete);
  312. }
  313.  
  314. TypeingCommand::~TypeingCommand()
  315. {
  316.     SafeDelete(backspaceBuf);
  317.     SafeDelete(newText);
  318. }
  319.  
  320. void TypeingCommand::Done(Command *newCmd)
  321. {
  322.     if (newCmd != this) {
  323.     if (newCmd == 0 || newCmd->GetId() != cTYPEING) {
  324.         SetFlag(eCmdDoDelete);
  325.         tv->TypeingDeleted();
  326.     } else
  327.         completed= TRUE;
  328.     }
  329. }
  330.  
  331. void TypeingCommand::UndoIt()
  332. {
  333.     Text *t= tv->GetText();
  334.     int firstNewChar;
  335.  
  336.     firstNewChar= min(oldStart - backspaceBuf->Size(),oldStart);
  337.     if (firstNewChar != newStart) {                     // save new text
  338.     t->Copy(newText, firstNewChar, newStart);         
  339.     tv->SetSelection(firstNewChar, newStart, TRUE);
  340.     tv->Cut();                                      // remove new text
  341.     } else
  342.     tv->SetSelection(firstNewChar, newStart, TRUE);
  343.     if (backspaceBuf->Size())                            
  344.     tv->Paste(backspaceBuf);                        // insert saved text
  345.     if (oldText->Size())
  346.     tv->Paste(oldText);
  347.     RestoreSelection();
  348.     tv->RevealSelection();
  349. }
  350.  
  351. void TypeingCommand::RedoIt()
  352. {
  353.     RestoreSelection();
  354.     tv->Cut();
  355.     if (backspaceBuf->Size()) {
  356.     tv->SetSelection(oldStart - backspaceBuf->Size(), oldStart, FALSE);
  357.     tv->Cut();        
  358.     }
  359.     if (newText->Size())
  360.     tv->Paste(newText);
  361.     tv->RevealSelection();
  362. }
  363.  
  364. void TypeingCommand::AddChar(int n)
  365.     newStart+= n; 
  366. }
  367.  
  368. void TypeingCommand::DelChar()
  369. {
  370.     Text *t= tv->GetText();
  371.  
  372.     if (newStart > 0)
  373.     newStart--;  
  374.     if (newStart < oldStart) 
  375.     if (oldStart - newStart > backspaceBuf->Size()) { // char already saved??
  376.         Text *tmp= t->Save(newStart, newStart+1);
  377.         backspaceBuf->Paste(tmp, 0, 0);
  378.         SafeDelete(tmp);
  379.     }
  380. }
  381.  
  382. //---- class ChangeStyle -------------------------------------------------------
  383.  
  384. MetaImpl(ChangeStyleCommand, (TP(newStyles), TP(oldStyles), TP(tvp), TE(mode), 0));
  385.  
  386. ChangeStyleCommand::ChangeStyleCommand(TextView *t, int cmdNo, char *cmdName, 
  387.        StChangeStyle m, StyleSpec ns) : TextCommand(t, cmdNo, cmdName, FALSE)
  388. {
  389.     if (!t->GetText()->IsKindOf(StyledText))
  390.     Error("ChangeStyleCommand::ChangeStyleCommand",
  391.                 "Apply ChangeStyleCommands only to StyledText");
  392.     newStyles= oldStyles= 0;
  393.     tvp= t; 
  394.     style= ns;
  395.     mode= m;
  396. }
  397.  
  398. void ChangeStyleCommand::DoIt()
  399. {
  400.     int from, to;
  401.     StyledText *sp= (StyledText*) tvp->GetText();
  402.  
  403.     tvp->GetSelection(&from, &to);
  404.     if (tvp->Caret())
  405.     sp->SetStyle (mode, from, to, style);
  406.     else {    
  407.     if (oldStyles == 0) 
  408.         oldStyles= new RunArray;
  409.     sp->CopyStyles (oldStyles, from, to);
  410.     sp->SetStyle (mode, from, to, style);
  411.     }
  412.     tvp->RevealSelection();
  413. }  
  414.  
  415. void ChangeStyleCommand::UndoIt()
  416. {
  417.     StyledText *sp= (StyledText*) tvp->GetText();
  418.  
  419.     if (oldStart == oldEnd)
  420.     sp->ResetCurrentStyle();
  421.     else {
  422.     if (newStyles == 0) {
  423.         newStyles= new RunArray;
  424.         sp->CopyStyles (newStyles, oldStart, oldEnd);
  425.     }
  426.     sp->ReplaceStyles (oldStyles, oldStart, oldEnd); 
  427.     }
  428.     RestoreSelection();
  429.     tvp->RevealSelection();
  430. }
  431.  
  432. void ChangeStyleCommand::RedoIt()
  433. {
  434.     StyledText *sp= (StyledText*) tvp->GetText();
  435.     if (oldStart == oldEnd)
  436.     sp->SetStyle(mode, oldStart, oldEnd, style);        
  437.     else
  438.     sp->ReplaceStyles(newStyles, oldStart, oldEnd); 
  439.     RestoreSelection();
  440.     tvp->RevealSelection();
  441. }
  442.